goog.provide('dk.util');

goog.require('goog.dom.classes');
goog.require('goog.string');


/**
 * @param {goog.dom.DomHelper} domHelper
 * @param {function(Element)} f
 */
dk.util.forEachElementChild = function(domHelper, f) {
  var body = domHelper.getDocument().body;
  for (var el = domHelper.getFirstElementChild(body);
       el;
       el = domHelper.getNextElementSibling(el)) {
    // This is the buffer used for the cursor manager.
    if (el.style.position == 'absolute') {
      continue;
    }
    
    f(el);
  }
};

/**
 * Replaces a double hyphen with an &mdash; Only do this outside of code samples.
 * @param {string} text
 * @return {string}
 */
dk.util.fixMDash = function(text) {
  return text.replace(/\s*--\s*/g, '&mdash;');
};

/**
 * @param {!Element} el
 * @return {boolean}
 */
dk.util.isParagraph = function(el) {
  return goog.dom.classes.has(el, 'paragraph');
};

/**
 * @param {!Element} el
 * @return {boolean}
 */
dk.util.isListItem = function(el) {
  return goog.dom.classes.has(el, 'list-item');
};

/**
 * @param {!Element} el
 * @return {boolean}
 */
dk.util.isH1 = function(el) {
  return goog.dom.classes.has(el, 'big-heading');
};

/**
 * @param {!Element} el
 * @return {boolean}
 */
dk.util.isH2 = function(el) {
  return goog.dom.classes.has(el, 'heading');
};

/**
 * @param {!Element} el
 * @return {boolean}
 */
dk.util.isH3 = function(el) {
  return goog.dom.classes.has(el, 'small-heading');
};

/**
 * @param {!Element} el
 * @return {boolean}
 */
dk.util.isSourceCode = function(el) {
  return goog.dom.classes.has(el, 'source-code');
};

/**
 * @type {RegExp}
 */
dk.util.linkRe = /\[\[([^\[]*)\]\]/g;

/**
 * @type {RegExp}
 */
dk.util.xrefPrefix = 'xref:';

/**
 * @param {string} sgml
 * @return {string}
 */
dk.util.formatXmlLink = function(sgml) {
  // Replace [[http://www.google.com]] with <ulink url="http://www.google.com"/>
  // Replace [[xref:closure-service-ui]] with <xref linkend="closure-service-ui"/>
  return sgml.replace(dk.util.linkRe, function(link) {
    var text = link.substring(2, link.length - 2);
    if (goog.string.startsWith(text, dk.util.xrefPrefix)) {
      text = text.substring(dk.util.xrefPrefix.length);
      var firstSpace = text.indexOf(' ');
      if (firstSpace >= 0) {
        text = text.substring(0, firstSpace);
      }
      return '<xref linkend="' + text + '"/>';
    } else {
      var firstSpace = text.indexOf(' ');
      var href = text.substring(0, firstSpace);
      var linkText = text.substring(firstSpace + 1);
      return '<ulink url="' + href + '">' + linkText + '</ulink>';
    }
  });  
};

/**
 * @param {string} sgml
 * @return {string}
 */
dk.util.formatHtmlLink = function(sgml) {
  // Replace [[http://www.google.com]] with
  // <a href="http://www.google.com" target="_blank">http://www.google.com</a>
  // Replace [[xref:closure-service-ui]] with
  // <a href="#closure-service-ui">closure-service-ui</a>
  return sgml.replace(dk.util.linkRe, function(link) {
    var text = link.substring(2, link.length - 2);
    if (goog.string.startsWith(text, dk.util.xrefPrefix)) {
      text = text.substring(dk.util.xrefPrefix.length);

      // TODO(bolinfest): Insert appropriate reference text when there is no space.
      var firstSpace = text.indexOf(' ');
      var href = text.substring(0, firstSpace);
      var linkText = text.substring(firstSpace + 1);
      return '<a href="#' + href + '">' + linkText + '</a>';
    } else {
      var firstSpace = text.indexOf(' ');
      var href = text.substring(0, firstSpace);
      var linkText = text.substring(firstSpace + 1);
      return '<a href="' + href + '" target="_blank">' + linkText + '</a>';
    }
  });  
};

/**
 * @type {RegExp}
 */
dk.util.italicRe = /::(.?[^:])*::/g;

/**
 * @param {string} tagName
 * @param {string} str
 * @return {string}
 */
dk.util.formatEmphasisPattern = function(tagName, str) {
  return str.replace(dk.util.italicRe, function(italic) {
    var text = italic.substring(2, italic.length - 2);
    return '<' + tagName + '>' + text + '</' + tagName + '>';
  });
};

/**
 * @param {string} str
 * @return {string}
 */
dk.util.formatEmphasis = goog.partial(dk.util.formatEmphasisPattern, 'emphasis');

/**
 * @param {string} str
 * @return {string}
 */
dk.util.formatEm = goog.partial(dk.util.formatEmphasisPattern, 'em');

/**
 * @param {string} sgml
 * @return {string}
 */
dk.util.formatBackquote = function(sgml) {
  var splitOnBackquote = sgml.split('`');
  if (splitOnBackquote.length % 2 != 1) {
    throw new Error('Last code element was not closed in ' + sgml);
  }

  var newSgml = [];
  for (var i = 0; i < splitOnBackquote.length; i++) {
    var str = splitOnBackquote[i];
    if (i % 2 == 0) {
      newSgml.push(dk.util.fixMDash(str));
    } else {
      newSgml.push('<code>', str, '</code>');
    }
  }
  return newSgml.join('');
};
